package com.shangxian.giveithome.service.impl;


import com.shangxian.giveithome.code.CommonCode;
import com.shangxian.giveithome.code.PetCode;
import com.shangxian.giveithome.controller.ImgFeiServer;
import com.shangxian.giveithome.controller.MechanismServer;
import com.shangxian.giveithome.controller.SearchPeoplePoster;
import com.shangxian.giveithome.controller.UserFeiController;
import com.shangxian.giveithome.entity.*;
import com.shangxian.giveithome.entity.community.IssueImg;
import com.shangxian.giveithome.entity.community.IssueList;
import com.shangxian.giveithome.entity.community.UserList;
import com.shangxian.giveithome.exception.ExceptionUtils;
import com.shangxian.giveithome.mapper.*;
import com.shangxian.giveithome.properties.RedisProperties;
import com.shangxian.giveithome.service.PetService;
import com.shangxian.giveithome.utils.IGenerator;
import com.shangxian.giveithome.utils.MyBeanUtils;
import com.shangxian.giveithome.utils.PageUtils;
import com.shangxian.giveithome.utils.RedisUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.shangxian.giveithome.code.PetCode.AGREEMENT_2_ERROR;
import static com.shangxian.giveithome.properties.PetProperties.*;
import static com.shangxian.giveithome.utils.DateTime.YMD;
import static com.shangxian.giveithome.utils.DateTime.getTime;


@Service
public class PetServiceImpl implements PetService {

    @Resource
    private PetMapper petMapper;

    @Resource
    private ImgFeiServer imgFeiServer;

    @Resource
    private MechanismServer mechanismServer;

    @Resource
    private UserFeiController userFeiController;

    @Resource
    private SearchMapper searchMapper;

    @Resource
    private PlaceMapper placeMapper;

    @Resource
    private IGenerator iGenerator;

    @Resource
    private AdoptionMapper adoptionMapper;

    @Resource
    private HttpServletRequest request;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private CollectionsMapper collectionsMapper;

    @Resource
    private IssueMapper issueMapper;

    @Resource
    private IssueImgMapper issueImgMapper;

    @Resource
    private AttentionMapper attentionMapper;

    @Resource
    private UserMapper userMapper;

    /**
     * 按条件查看寻宠
     *
     * @param searchScreen
     * @param pageable
     * @return
     */
    @Override
    public PageableDetails querySearchPet(SearchScreen searchScreen, Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        Integer total = petMapper.queryCountSearchPet(searchScreen);
        //构造存储容器
        List<SearchPetList> extraList = new ArrayList<>(pageSize);
        if (total< 20 && !"莆田市".equals(searchScreen.getCity()) && pageNumber == 0){
            SearchScreen screen = new SearchScreen();
            screen.setCity("莆田市");
            extraList = petMapper.querySearchPet(screen, 0, 20-total);
        }
        //total
        int totalAll =total + extraList.size();
        if (totalAll <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }

        //stream()优点
        //
        //无存储。stream不是一种数据结构，它只是某种数据源的一个视图，数据源可以是一个数组，Java容器或I/O channel等。
        //为函数式编程而生。对stream的任何修改都不会修改背后的数据源，比如对stream执行过滤操作并不会删除被过滤的元素，而是会产生一个不包含被过滤元素的新stream。
        //惰式执行。stream上的操作并不会立即执行，只有等到用户真正需要结果的时候才会执行。
        //可消费性。stream只能被“消费”一次，一旦遍历过就会失效，就像容器的迭代器那样，想要再次遍历必须重新生成。
        // stream().map()方法的使用示例:List<Long> ids = searchPetLists.stream().map(SearchPetList::getImgId).collect(Collectors.toList());
        //该方法中的searchPetLists  为一个实体类的集合，类型为List<SearchPetList>   SearchPetList :为实体类  getImgId：实体类中的
        //get方法， 为获取SearchPetList类中的 imgId  即获得所有的图片id 然后查询所有的图片类中的信息
        List<SearchPetList> searchPetLists = petMapper.querySearchPet(searchScreen, pageNumber * pageSize, pageSize);
        if (extraList.size() != 0){
            //拼接数据
            searchPetLists.addAll(extraList);
        }
        if (searchPetLists.size() <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }
        List<Long> ids = searchPetLists.stream().map(SearchPetList::getImgId).collect(Collectors.toList());
        List<Img> imgs = imgFeiServer.queryImagesByIds(ids);

        searchPetLists.forEach(searchPetList -> {
            imgs.forEach(img -> {
                if (img.getKeyId().equals(searchPetList.getImgId())) {
                    searchPetList.setPath(img.getPath());
                    System.out.println(img.getPath());
                    searchPetList.setImgId(null);
                }
            });
        });
        return new PageableDetails<>(pageNumber, pageSize, total+extraList.size(), returnPages(total+extraList.size(), pageSize), searchPetLists);
    }

    /**
     * 查看寻宠详情
     *
     * @param id
     * @return
     */
    @Override
    public SearchPetDetailsS querySearchPetDetails(Long id) {
        Pet pet = petMapper.querySearchPetDetails(id);
        if (pet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        SearchPet searchPet = searchMapper.searchPetDetails(id);
        if (searchPet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }

        SearchPetDetailsS searchPetDetailsS = new SearchPetDetailsS(pet);
        MyBeanUtils.copyBeanNull(searchPet, searchPetDetailsS.getSearchPetDetails());
        List<Img> imgs = imgFeiServer.queryImagesByImgs(searchPet.getImgId());
        System.out.println(imgs);
        searchPetDetailsS.getSearchPetDetails().setImg(imgs);
        if (pet.getMeId() != 0) {
            Mechanism mechanism = mechanismServer.queryByMechanismId(pet.getMeId());
            searchPetDetailsS.setName(mechanism.getName());
            searchPetDetailsS.setImages(mechanism.getPicture());
        } else {
            UserSimple userSimple = userFeiController.queryUsById(pet.getUsId());
            searchPetDetailsS.setName(userSimple.getName());
            searchPetDetailsS.setImages(userSimple.getPicture());
        }
        return searchPetDetailsS;
    }

    /**
     * 查询寻主列表
     *
     * @param searchScreen
     * @param pageable
     * @return
     */
    @Override
    public PageableDetails querySearchPeople(SearchScreen searchScreen, Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        Integer total = petMapper.queryCountSearchPeople(searchScreen);
        //构造存储容器
        List<SearchPeopleList> extraList = new ArrayList<>(pageSize);
        if (total< 20 && !"莆田市".equals(searchScreen.getCity()) && pageNumber == 0){
            SearchScreen screen = new SearchScreen();
            screen.setCity("莆田市");
            extraList = petMapper.querySearchPeople(screen, 0, 20-total);
        }
        //total
        int totalAll =total + extraList.size();
        if (totalAll <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }
        List<SearchPeopleList> searchPeopleLists = petMapper.querySearchPeople(searchScreen, pageNumber * pageSize, pageSize);
        if (extraList.size() != 0){
            //拼接数据
            searchPeopleLists.addAll(extraList);
        }
        if (searchPeopleLists.size() <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }
        List<Long> ids = searchPeopleLists.stream().map(SearchPeopleList::getImgId).collect(Collectors.toList());
        List<Img> imgs = imgFeiServer.queryImagesByIds(ids);
        searchPeopleLists.forEach(searchPeopleList -> {
            imgs.forEach(img -> {
                if (img.getKeyId().equals(searchPeopleList.getImgId())) {
                    searchPeopleList.setPath(img.getPath());
                    searchPeopleList.setImgId(null);
                }
            });
        });
        return new PageableDetails<>(pageNumber, pageSize, total+extraList.size(), returnPages(total+extraList.size(), pageSize), searchPeopleLists);
    }

    /**
     * 查看寻主详情
     *
     * @param id
     * @return
     */
    @Override
    public SearchPeopleDetailsS querySearchPeopleDetails(Long id) {
        Pet pet = petMapper.querySearchPeopleDetails(id);
        if (pet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        SearchPeople searchPeople = searchMapper.searchPeopleDetails(id);
        if (searchPeople == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }

        SearchPeopleDetailsS searchPeopleDetails = new SearchPeopleDetailsS(pet);
        MyBeanUtils.copyBeanNull(searchPeople, searchPeopleDetails.getSearchPeopleDetails());
        List<Img> imgs = imgFeiServer.queryImagesByImgs(searchPeople.getImgId());
        searchPeopleDetails.getSearchPeopleDetails().setImg(imgs);
        if (pet.getMeId() != 0) {
            Mechanism mechanism = mechanismServer.queryByMechanismId(pet.getMeId());
            searchPeopleDetails.setName(mechanism.getName());
            searchPeopleDetails.setImages(mechanism.getPicture());
        } else {
            UserSimple userSimple = userFeiController.queryUsById(pet.getUsId());
            searchPeopleDetails.setName(userSimple.getName());
            searchPeopleDetails.setImages(userSimple.getPicture());
        }
        return searchPeopleDetails;
    }

    /**
     * 查询全部
     *
     * @param searchScreen
     * @param pageable
     * @return
     */
    @Override
    public PageableDetails querySearchAll(SearchScreen searchScreen, Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        Integer total = petMapper.queryCountSearchAll(searchScreen);
        //构造容器存储不满足情况数据
        List<SearchAllList> extraList = new ArrayList<>(pageSize);
        if (pageable.getPageSize() < 10 && !"莆田市".equals(searchScreen.getCity()) && pageNumber == 0) {
            if (total < 6) {
                //如果该省份首页数据小于6条
                SearchScreen searchScreen1 = new SearchScreen();
                searchScreen1.setCity("莆田市");
                extraList = petMapper.querySearchAll(searchScreen1, 0, 6 - total);
            }
        }

        if (pageable.getPageSize() == 20 && !"莆田市".equals(searchScreen.getCity()) && pageNumber == 0){
            if (total < 20){
                //如果该省份全部列表数据小于20条
                SearchScreen searchScreen1 = new SearchScreen();
                searchScreen1.setCity("莆田市");
                extraList = petMapper.querySearchAll(searchScreen1, 0, 20 - total);

            }
        }
        int totalAll = extraList.size() + total;
        if (totalAll <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }
        List<SearchAllList> searchAllLists = petMapper.querySearchAll(searchScreen, pageNumber * pageSize, pageSize);
        if (extraList.size() != 0){
            //拼接数据
            searchAllLists.addAll(extraList);
        }
        if (searchAllLists.size() <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }
        List<Long> ids = searchAllLists.stream().map(SearchAllList::getImgId).collect(Collectors.toList());
        List<Img> imgs = imgFeiServer.queryImagesByIds(ids);
        searchAllLists.forEach(searchAllList -> {
            imgs.forEach(img -> {
                if (img.getKeyId().equals(searchAllList.getImgId())) {
                    searchAllList.setPath(img.getPath());
                    searchAllList.setImgId(null);
                }
            });
        });

        return new PageableDetails<>(pageNumber, pageSize, total+extraList.size(), returnPages(total+extraList.size(), pageSize), searchAllLists);

    }

    @Override
    public List<PlaceMechanism> queryPlaceMe(Long id, Integer n) {
        List<Place> places = searchMapper.queryPlaceMe(id, 0, n);
        if (CollectionUtils.isEmpty(places)) {
            ExceptionUtils.error(CommonCode.DATA_ERROR);
        }
        List<Long> collect = places.stream().map(Place::getPetId).collect(Collectors.toList());
        List<Pet> pets = petMapper.queryPlace(collect);
        if (CollectionUtils.isEmpty(pets)) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        List<Long> imgs = places.stream().map(Relationship::getImgId).collect(Collectors.toList());
        List<Img> img = imgFeiServer.queryImagesByIds(imgs);
        List<PlaceMechanism> placeMechanisms = new ArrayList<>();
        pets.forEach(pet -> {
            PlaceMechanism placeMechanism = new PlaceMechanism();
            placeMechanism.setPetDetails(new PetDetails(pet));
            places.forEach(place -> {
                if (place.getPetId().equals(pet.getId())) {
                    List<Img> imgList = new ArrayList<>();
                    img.forEach(img1 -> {
                        if (img1.getKeyId().equals(place.getImgId())) {
                            imgList.add(img1);
                        }
                    });
                    placeMechanism.getPetDetails().setImg(imgList);
                }
            });
            placeMechanisms.add(placeMechanism);
        });
        return placeMechanisms;
    }

    /**
     * 查看领养页面列表
     *
     * @param placeScreen
     * @param pageable
     * @return
     */
    @Override
    public PageableDetails queryPlace(PlaceScreen placeScreen, Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        Integer total = petMapper.queryCountPlace(placeScreen);
        //构造存储容器
        List<PlaceLists> extraList = new ArrayList<>(pageSize);
        if (total< 20  && !"莆田市".equals(placeScreen.getCity()) && pageNumber == 0){
            PlaceScreen screen = new PlaceScreen();
            screen.setCity("莆田市");
            extraList = petMapper.queryPlacesList(screen, 0, 20-total);
        }
        //total
        int totalAll =total + extraList.size();
        if (totalAll <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }
        //List<Pet> pets = petMapper.queryPlaces(placeScreen, pageNumber * pageSize, pageSize);
        //List<PlaceLists> placeLists = iGenerator.convert(pets, PlaceLists.class);
        List<PlaceLists> placeLists = petMapper.queryPlacesList(placeScreen, pageNumber * pageSize, pageSize);

        if (extraList.size() != 0){
            placeLists.addAll(extraList);
        }
        if (placeLists.size() <= 0) {
            return new PageableDetails<>(0, 0, 0, 1, new ArrayList<>());
        }
        List<Long> collect = placeLists.stream().map(PlaceLists::getId).collect(Collectors.toList());
        List<Place> places = placeMapper.queryByPlaces(collect, PLACE_STATUS_1);
        List<Long> imgIdS = places.stream().map(Relationship::getImgId).collect(Collectors.toList());
        List<Img> imgs = imgFeiServer.queryImagesByIds(imgIdS);
        placeLists.forEach(placeScreen1 -> {
            places.forEach(place -> {
                imgs.forEach(img -> {
                    if (img.getKeyId().equals(place.getImgId()) && place.getPetId().equals(placeScreen1.getId())) {
                        placeScreen1.setImgPath(img.getPath());
                    }
                });
            });
        });

        return new PageableDetails<>(pageNumber, pageSize, total+extraList.size(), returnPages(total+extraList.size(), pageSize), placeLists);
    }

    /**
     * 查询领养详情
     *
     * @param id
     * @return
     */
    @Override
    public PlaceDetailsS queryPlaceDetails(Long id) {

        Pet pet = petMapper.queryPlaceDetails(id);
        if (pet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        Place place = placeMapper.queryByDetails(id);
        if (place == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        PlaceDetailsS placeDetailsS = new PlaceDetailsS(pet);
        MyBeanUtils.copyBeanNull(place, placeDetailsS.getPlaceDetails());
        List<Img> imgs = imgFeiServer.queryImagesByImgs(place.getImgId());
        placeDetailsS.getPlaceDetails().setImg(imgs);
        if (pet.getMeId() != 0) {
            Mechanism mechanism = mechanismServer.queryByMechanismId(pet.getMeId());
            placeDetailsS.setName(mechanism.getName());
            placeDetailsS.setImages(mechanism.getPicture());
        } else {
            UserSimple userSimple = userFeiController.queryUsById(pet.getUsId());
            placeDetailsS.setName(userSimple.getName());
            placeDetailsS.setImages(userSimple.getPicture());
        }

        return placeDetailsS;
    }

    /**
     * 创建寻宠发布
     *
     * @param searchPetCreate
     */
    @Override
    @Transactional
    public int createSearchPet(SearchPetCreate searchPetCreate) {
        searchPetCreate.setSubordinate(TYPE_SEARCH_PET);
        // 保存丢失时间
        Date loseTime = searchPetCreate.getCreateTime();
        // 设置该信息创建时间
        searchPetCreate.setCreateTime(getTime(YMD));
        petMapper.saveSearchPet(searchPetCreate);
        searchPetCreate.setCreateTime(loseTime);
        searchMapper.save(searchPetCreate);
        // 更新用户数据
        this.updateUserData(searchPetCreate.getUsId(), TYPE_SEARCH_PET);
        return searchPetCreate.getId().intValue();
    }

    /**
     * 修改寻宠信息
     *
     * @param searchPetUpdate
     */
    @Override
    @Transactional
    public void updateSearchPet(SearchPetUpdate searchPetUpdate) {
        searchPetUpdate.setSubordinate(TYPE_SEARCH_PET);
        petMapper.updateSearchPet(searchPetUpdate);
        searchMapper.update(searchPetUpdate);
    }

    /**
     * 删除寻宠
     *
     * @param id
     */
    @Override
    @Transactional
    public void deleteSearchPet(Long id) {
        petMapper.delete(id);
        searchMapper.delete(id);
    }

    /**
     * 修改寻宠状态
     *
     * @param id
     */
    @Override
    @Transactional
    public void updateSearchPetStatus(Long id) {
        searchMapper.updateStatus(id, 1);
    }

    /**
     * 寻主发布
     *
     * @param searchPeopleCreate
     */
    @Override
    @Transactional
    public int createSearchPeople(SearchPeopleCreate searchPeopleCreate) {
        searchPeopleCreate.setSubordinate(TYPE_SEARCH_PEOPLE);
        // 保存发现时间
        Date findTime = searchPeopleCreate.getCreateTime();
        // 设置该信息创建时间
        searchPeopleCreate.setCreateTime(getTime(YMD));
        petMapper.saveSearchPeoplet(searchPeopleCreate);
        searchPeopleCreate.setCreateTime(findTime);
        searchMapper.savPeople(searchPeopleCreate);
        // 更新用户数据
        this.updateUserData(searchPeopleCreate.getUsId(), TYPE_SEARCH_PEOPLE);
        return searchPeopleCreate.getId().intValue();
    }

    /**
     * 修改寻主信息
     *
     * @param searchPeopleUpdate
     */
    @Override
    @Transactional
    public void updateSearchPeople(SearchPeopleUpdate searchPeopleUpdate) {
        searchPeopleUpdate.setSubordinate(TYPE_SEARCH_PEOPLE);
        petMapper.updateSearchPeople(searchPeopleUpdate);
        searchMapper.updatePeople(searchPeopleUpdate);
    }

    /**
     * 删除寻主
     * @param id
     */
    @Override
    @Transactional
    public void deleteSearchPeople(Long id) {
        petMapper.delete(id);
        searchMapper.deletePeople(id);
    }

    /**
     * 找到主人了
     * @param id
     */
    @Override
    public void updateSearchPeopleStatus(Long id) {
        searchMapper.updatePeopleStatus(id, 1);
    }

    /**
     * 发布领养
     * @param placeCreate
     */
    @Override
    @Transactional
    public int createPlace(PlaceCreate placeCreate) {
        placeCreate.setSubordinate(TYPE_PLACE_OUT_ADOPT);
        // 设置该信息创建时间
        placeCreate.setCreateTime(getTime(YMD));
        petMapper.savePlaceOutAdopt(placeCreate);
        placeMapper.savePlace(placeCreate);
        // 更新用户数据
        this.updateUserData(placeCreate.getUsId(), TYPE_PLACE_OUT_ADOPT);
        return placeCreate.getId().intValue();
    }

    /**
     * 修改领养
     * @param placeUpdate
     */
    @Override
    @Transactional
    public void updatePlace(PlaceUpdate placeUpdate) {
        placeUpdate.setSubordinate(TYPE_PLACE_OUT_ADOPT);
        placeUpdate.setStatus(PLACE_STATUS_1);
        petMapper.updatePlace(placeUpdate);
        placeMapper.updatePlace(placeUpdate);
    }

    /**
     * 领养协议创建-送养方修改图片信息
      * @param adoptionImg
     * @param id 用户id
     */
    @Override
    @Transactional
    public void updateAdoptionImg(AdoptionImg adoptionImg, Long id) {
        Adoption adoption = this.queryAdoption(adoptionImg.getPetId());
        if (adoption == null) {
            // 协议尚未创建
            ExceptionUtils.error(PetCode.AGREEMENT_1_ERROR);
        } else if (!adoption.getAdId().equals(0)) {
            // 该宠物已被领养
            ExceptionUtils.error(PetCode.AGREEMENT_2_ERROR);
        } else if (!adoption.getUsId().equals(id)) {
            // 该宠物不是该用户的
            ExceptionUtils.error(PetCode.NOT_AUTH_OP_PET);
        }
        adoptionMapper.updateImgByPetId(adoptionImg.getImgId(), adoptionImg.getPetId());
    }

    /**
     * 创建领养协议-送养方
     * @param adoptionCreate
     */
    @Override
    @Transactional
    public void createAdoption(AdoptionCreate adoptionCreate) {
        Place place = placeMapper.querySimPlaceById(adoptionCreate.getPetId(), PLACE_STATUS_1);
        Adoption adoption = adoptionCreate.getAdoption();
        // 如果该宠物不存在或者不属于该用户
        if (place == null || !place.getUsId().equals(adoption.getUsId())) {
            ExceptionUtils.error(PetCode.NOT_AUTH_OP_PET);
        }
        Integer count = adoptionMapper.queryByPlaceSu(adoptionCreate.getPetId());
        // 该宠物领养协议已创建
        if (count != 0) {
            // do nothing
            return;
        }
        // 设置图片id和领养时间
        adoption.setImgId(adoptionCreate.getImgId());
        adoption.setCreateTime(getTime(YMD));
        adoptionMapper.save(adoption);
        adoptionCreate.setRole(PLACE_PEOPLE);
        adoptionMapper.saveAgreement(adoptionCreate);
    }

    /**
     * 领养协议完成-领养方
     * @param adoptionComplete
     */
    @Override
    @Transactional
    public void adoptionComplete(AdoptionComplete adoptionComplete) {
        // 修改领养表信息
        adoptionMapper.updateAdIdByPetId(adoptionComplete.getAd_id(), adoptionComplete.getPetId(), getTime(YMD));
        adoptionComplete.setRole(ADOPT_PEOPLE);
        // 填写协议
        adoptionMapper.saveAgreement_2(adoptionComplete);
        // 改变宠物状态
        int count = placeMapper.updateStatus(adoptionComplete.getPetId(), PLACE_STATUS_1, PLACE_STATUS_2);
        // 更新用户数据
        if (count == 1) {
            updateUserData(adoptionComplete.getAd_id(), TYPE_ADOPT);
        }
    }

    /**
     * 领养协议是否存在
     * @param petId
     * @return
     */
    @Override
    public Adoption queryAdoption(Long petId) {
        return adoptionMapper.queryAdoptionById(petId);
    }

    /**
     * 查看寻宠海报信息
     * @param wxCodeUnLimit
     * @return
     */
    @Override
    public SearchPetPoster querySearchPetPoster(WxCodeUnLimit wxCodeUnLimit) {
        // 获取寻宠信息
        Long petId = Long.valueOf(wxCodeUnLimit.getScene());
        Pet pet = petMapper.querySimpleSearchPet(petId);
        if (pet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        SearchPet searchPet = searchMapper.searchPetDetails(petId);
        if (searchPet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }

        SearchPetDetailsS searchPetDetailsS = new SearchPetDetailsS(pet);
        MyBeanUtils.copyBeanNull(searchPet, searchPetDetailsS.getSearchPetDetails());
        List<Img> imgs = imgFeiServer.queryImagesByImgs(searchPet.getImgId());
        searchPetDetailsS.getSearchPetDetails().setImg(imgs);

        SearchPetPoster searchPetPoster = new SearchPetPoster(searchPetDetailsS);
        // 获取宠物二维码图片
        searchPetPoster.setPath(imgFeiServer.queryPetQrCode(wxCodeUnLimit));
        return searchPetPoster;
    }

    /**
     * 查看寻主海报信息
     * @param wxCodeUnLimit
     * @return
     */
    @Override
    public SearchPeoplePoster querySearchPeoplePoster(WxCodeUnLimit wxCodeUnLimit) {
        Long petId = Long.valueOf(wxCodeUnLimit.getScene());
        Pet pet = petMapper.querySimpleSearchPeople(petId);
        if (pet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        SearchPeople searchPeople = searchMapper.searchPeopleDetails(petId);
        if (searchPeople == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }

        SearchPeopleDetailsS searchPeopleDetails = new SearchPeopleDetailsS(pet);
        MyBeanUtils.copyBeanNull(searchPeople, searchPeopleDetails.getSearchPeopleDetails());
        List<Img> imgs = imgFeiServer.queryImagesByImgs(searchPeople.getImgId());
        searchPeopleDetails.getSearchPeopleDetails().setImg(imgs);

        SearchPeoplePoster searchPeoplePoster = new SearchPeoplePoster(searchPeopleDetails);
        // 获取宠物二维码图片
        searchPeoplePoster.setPath(imgFeiServer.queryPetQrCode(wxCodeUnLimit));
        return searchPeoplePoster;
    }

    /**
     * 查看领养海报信息
     * @param wxCodeUnLimit
     * @return
     */
    @Override
    public PlacePoster queryPlacePoster(WxCodeUnLimit wxCodeUnLimit) {
        Long petId = Long.valueOf(wxCodeUnLimit.getScene());
        Pet pet = petMapper.querySimplePlace(petId);
        if (pet == null) {
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        PlaceDetails placeDetails = new PlaceDetails(pet);
        Place place = placeMapper.queryByDetails(petId);
        MyBeanUtils.copyBeanNull(place, placeDetails);
        List<Img> imgs = imgFeiServer.queryImagesByImgs(place.getImgId());
        placeDetails.setImg(imgs);

        PlacePoster placePoster = new PlacePoster(placeDetails);
        // 获取宠物二维码图片
        placePoster.setPath(imgFeiServer.queryPetQrCode(wxCodeUnLimit));
        return placePoster;
    }

    //拉取猫狗品种列表
    @Override
    public VarietiesResultList getPetVarieties() {
        Object varietiesObj = redisUtils.getRedis(RedisProperties.PET_VARIETIES);
        // 如果redis里有缓存，则直接返回
        if (varietiesObj != null && varietiesObj instanceof VarietiesResultList) {
            return (VarietiesResultList) varietiesObj;
        }
        VarietiesResultList result =  getVarietiesResultList();
        redisUtils.setKey(RedisProperties.PET_VARIETIES, result);
        return result;
    }

    private VarietiesResultList getVarietiesResultList() {
        VarietiesResultList varietiesResultList=new VarietiesResultList();
        varietiesResultList.setCat(petMapper.selectCatVarieties());
        varietiesResultList.setDog(petMapper.selectDogVarieties());
        return varietiesResultList;
    }

    /**
     * 查询机构正在进行送养的宠物数量
     * @param id
     * @return
     */
    @Override
    public int queryPlaceMeCount(Long id) {
        return placeMapper.queryCountPlaceMe(id);
    }

    /**
     * 查询领养协议
     * @param petId
     * @return
     */
    @Override
    public AdoptionAgreementDetails queryAdoptionAgreement(Long petId) {
        // 送养者信息
        List<AdoptionAgreement> agreementList = adoptionMapper.queryAgreementById(petId);
        if (agreementList == null || agreementList.size() == 0) {
            ExceptionUtils.error(PetCode.AGREEMENT_1_ERROR);
        }
        UserSimple userASimple = adoptionMapper.findAUserSimpleByPetId(petId);
        UserSimple userSsimple = adoptionMapper.findSUserSimpleByPetId(petId);
        agreementList.forEach(Agreement ->{
              if (Agreement.getRole() ==1){
                  Agreement.setPicture(userSsimple.getPicture());
              }else {
                  Agreement.setPicture(userASimple.getPicture());
                  Agreement.setAdoptUserId(userASimple.getId());
              }
        });
        String imgPath = adoptionMapper.queryImgByPetId(petId);
        //领养者信息
        AdoptionAgreementDetails details = new AdoptionAgreementDetails(agreementList, imgPath);
        return details;
    }

    /**
     * 删除送养
     * @param petId
     * @param usId
     */
    @Override
    @Transactional
    public void delPlace(Long petId, Long usId) {
        synchronized (this) {
            Adoption adoption = adoptionMapper.queryAdoptionById(petId);
            // 该宠物已被领养
            if (adoption != null && !adoption.getAdId().equals(0)) {
                ExceptionUtils.error(AGREEMENT_2_ERROR);
            }
            // 删除送养宠物相关信息
            petMapper.deleteUsPet(petId, usId);
            placeMapper.deleteUsPet(petId, usId);
            if (adoption != null) {
                adoptionMapper.deleteUsAll(petId, usId);
            }
            this.updateUserDateReduce(usId, TYPE_PLACE_OUT_ADOPT);
        }
    }

    @Override
    public PageableDetails getPetDynamic(Long id, Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        Long collectionId = petMapper.findAdCollectionId(id);
        int total  = issueMapper.findCollectionIssueCount(collectionId);
        if (total ==0){
            return new PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),new ArrayList<>());
        }
        List<IssueList> CollectionsListDetails = collectionsMapper.findAttentionUserCollectionsListDetails(collectionId, pageNumber * pageSize, pageSize);
        System.out.println(CollectionsListDetails);
        if (CollectionsListDetails.size() !=0) {
            List<Long> ids = CollectionsListDetails.stream().map(IssueList::getImgId).collect(Collectors.toList());
            List<IssueImg> issueImgs = issueImgMapper.findIssueImgByIds(ids);
            UserList userLists = attentionMapper.findAttentionCollectionUserMessage(collectionId);
            CollectionsListDetails.forEach(issueList -> {
                issueList.setName(userLists.getName());
                issueList.setPicture(userLists.getPicture());
                issueList.setImgPath("");
                for (IssueImg issueImg : issueImgs) {
                    if (issueList.getImgId() != null && issueList.getImgId().equals(issueImg.getKeyId())) {
                        issueList.setImgPath(issueImg.getPath());
                        break;
                    }
                }
            });
        }
        return new PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),CollectionsListDetails);
    }

    /**
     * 返回总页数
     *
     * @param total
     * @param pageSize
     * @return
     */
    public int returnPages(int total, int pageSize) {
        return PageUtils.returnPages(total, pageSize);
    }

    private void updateUserData(Long userId, Integer type) {
        UserDataUpdate putUserData = new UserDataUpdate();
        putUserData.setId(userId);
        if (type.equals(TYPE_SEARCH_PET)) {
            putUserData.setSearchPet(1);
        } else if (type.equals(TYPE_SEARCH_PEOPLE)) {
            putUserData.setSearchPeople(1);
        } else if (type.equals(TYPE_ASYLUM)) {
            putUserData.setLoveNumber(1);
        } else if (type.equals(TYPE_PLACE_OUT_ADOPT)) {
            putUserData.setPlaceNumber(1);
        } else if (type.equals(TYPE_ADOPT)) {
            putUserData.setAdoptionNumber(1);
        }
        userFeiController.update_user_data(putUserData);
        UserData userData = userFeiController.queryUserData(userId);
        // 更新redis里的用户数据
        redisUtils.updateUserData(request, userData);
    }

    private void updateUserDateReduce(Long userId, Integer type) {
        UserDataUpdate putUserData = new UserDataUpdate();
        putUserData.setId(userId);
        if (type.equals(TYPE_SEARCH_PET)) {
            putUserData.setSearchPet(1);
        } else if (type.equals(TYPE_SEARCH_PEOPLE)) {
            putUserData.setSearchPeople(1);
        } else if (type.equals(TYPE_ASYLUM)) {
            putUserData.setLoveNumber(1);
        } else if (type.equals(TYPE_PLACE_OUT_ADOPT)) {
            putUserData.setPlaceNumber(1);
        } else if (type.equals(TYPE_ADOPT)) {
            putUserData.setAdoptionNumber(1);
        }
        userFeiController.updateUserDataReduce(putUserData);
        UserData userData = userFeiController.queryUserData(userId);
        // 更新redis里的用户数据
        redisUtils.updateUserData(request, userData);
    }


    /**
     * 返回
     *
     * @param pageNumber 当前页
     * @param pageSize   每页条数
     * @param count      总条数
     * @param list       返回数据
     * @param <T>        泛型
     * @return
     */
    public <T> PageableDetails returnPageable(int pageNumber, Integer pageSize, Integer count, List<T> list) {
        return new PageableDetails<>(pageNumber, pageSize, count, list);
    }



}
